package com.mars.admin.service.impl;

import com.mars.admin.entity.SysOssConfig;
import com.mars.admin.framework.oss.factory.FileUploadStrategyFactory;
import com.mars.admin.framework.oss.strategy.FileUploadStrategy;
import com.mars.admin.mapper.SysOssConfigMapper;
import com.mars.admin.service.ISysOssConfigService;
import com.mybatisflex.core.paginate.Page;
import com.mybatisflex.core.query.QueryWrapper;
import com.mybatisflex.spring.service.impl.CacheableServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.cache.annotation.Caching;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

import static com.mars.admin.entity.table.SysOssConfigTableDef.SYS_OSS_CONFIG;

/**
 * OSS配置 服务实现类
 * 继承 CacheableServiceImpl 获得更多便捷方法和缓存功能
 *
 * @author Mars.wq
 */
@Slf4j
@Service
@CacheConfig(cacheNames = "sysOssConfig")
public class SysOssConfigServiceImpl extends CacheableServiceImpl<SysOssConfigMapper, SysOssConfig> implements ISysOssConfigService {

    @Autowired
    private FileUploadStrategyFactory strategyFactory;

    @Override
    public Page<SysOssConfig> selectConfigPage(Page<SysOssConfig> page, QueryWrapper queryWrapper) {
        return this.page(page, queryWrapper);
    }

    @Override
    @Cacheable(key = "'key:' + #configKey")
    public SysOssConfig selectConfigByKey(String configKey) {
        QueryWrapper queryWrapper = QueryWrapper.create()
                .where(SYS_OSS_CONFIG.CONFIG_KEY.eq(configKey))
                .and(SYS_OSS_CONFIG.IS_DELETED.eq(0));
        return this.getOne(queryWrapper);
    }

    @Override
    @Cacheable(key = "'enabled'")
    public List<SysOssConfig> selectEnabledConfigs() {
        QueryWrapper queryWrapper = QueryWrapper.create()
                .where(SYS_OSS_CONFIG.STATUS.eq(1))
                .and(SYS_OSS_CONFIG.IS_DELETED.eq(0))
                .orderBy(SYS_OSS_CONFIG.CREATE_TIME.desc());
        return this.list(queryWrapper);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    @CacheEvict(allEntries = true)
    public boolean saveConfig(SysOssConfig config) {
        // 检查配置key是否重复
        SysOssConfig existing = selectConfigByKey(config.getConfigKey());
        if (existing != null) {
            throw new RuntimeException("配置key已存在: " + config.getConfigKey());
        }
        return this.save(config);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    @Caching(evict = {
        @CacheEvict(key = "'key:' + #config.configKey", condition = "#config.configKey != null"),
        @CacheEvict(key = "#config.id", condition = "#config.id != null"),
        @CacheEvict(key = "'enabled'")
    })
    public boolean updateConfig(SysOssConfig config) {
        // 检查配置key是否重复（排除自己）
        QueryWrapper queryWrapper = QueryWrapper.create()
                .where(SYS_OSS_CONFIG.CONFIG_KEY.eq(config.getConfigKey()))
                .and(SYS_OSS_CONFIG.ID.ne(config.getId()))
                .and(SYS_OSS_CONFIG.IS_DELETED.eq(0));
        
        SysOssConfig existing = this.getOne(queryWrapper);
        if (existing != null) {
            throw new RuntimeException("配置key已存在: " + config.getConfigKey());
        }
        
        return this.updateById(config);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    @CacheEvict(allEntries = true)
    public boolean deleteConfig(Long id) {
        return this.removeById(id);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    @CacheEvict(allEntries = true)
    public boolean deleteConfigs(List<Long> ids) {
        return this.removeByIds(ids);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    @Caching(evict = {
        @CacheEvict(key = "#id"),
        @CacheEvict(key = "'enabled'")
    })
    public boolean updateStatus(Long id, Integer status) {
        SysOssConfig config = new SysOssConfig();
        config.setId(id);
        config.setStatus(status);
        return this.updateById(config);
    }

    @Override
    public boolean testConnection(SysOssConfig config) {
        try {
            // 根据配置类型获取对应的策略
            FileUploadStrategy strategy = strategyFactory.getStrategy(config.getConfigKey());
            
            // 这里可以实现具体的连接测试逻辑
            // 比如创建一个测试文件上传，然后删除
            log.info("测试OSS配置连接: {}", config.getConfigKey());
            
            // 简单的测试，实际项目中可以上传一个小的测试文件
            return true;
        } catch (Exception e) {
            log.error("测试OSS配置连接失败: {}", config.getConfigKey(), e);
            return false;
        }
    }

    @Override
    @CacheEvict(allEntries = true)
    public void refreshCache() {
        log.info("清空OSS配置缓存");
        // @CacheEvict注解会自动清除sysOssConfig缓存空间的所有数据
    }
} 